package week5;

import jsjf.exceptions.ElementNotFoundException;
import jsjf.exceptions.EmptyCollectionException;

public class ProductList<T> {
    protected int count;
    protected LinearNode head, tail;

    public ProductList() {
        count = 0;
        head = tail = null;
    }

    public void addToFront(Product element) {
        LinearNode node = new LinearNode(element);
        LinearNode current = head;
        if (isEmpty())
        {
            head = node;
        }
        else
        {
            node.setNext(current);
            head = node;
        }

        count++;
    }

    public void addToRear(Product element) {
        LinearNode node = new LinearNode(element);

        if (isEmpty())
        {
            head = node;
        }
        else
        {
            tail.setNext(node);
        }
        tail = node;
        count++;
    }

    public void addAfter(Product element, T target) {
        LinearNode current = head;
        LinearNode node = new LinearNode(element);

        if (isEmpty())
        {
            head = node;
        }

        while ((current!= null) && (current.getElement().equals(element)))
        {
            current = current.getNext();
        }
        if(current.getNext() == null){
            current.setNext(node);
            tail = node;
        }else{
            node.setNext(current.getNext());
            current.setNext(node);
        }

        count++;
    }


    public Product removeFirst() {
        if(isEmpty())
        {
            throw new EmptyCollectionException("LinkedList");
        }

        LinearNode current = head;
        head = current.getNext();

        count--;

        return current.getElement();
    }

    public Product removeLast() {
        LinearNode previous = null;
        LinearNode current = head;

        if(isEmpty())
        {
            throw new EmptyCollectionException("LinkedList");
        }
        while (current.getNext() != null)
        {
            previous = current;
            current = current.getNext();
        }
        if (size() == 1)
            head = tail = null;
        else {
            tail = previous;
            tail.setNext(null);
        }
        count--;

        return current.getElement();
    }

    public Product remove(T targetelement) throws EmptyCollectionException, ElementNotFoundException {
        if(isEmpty())
        {
            throw new EmptyCollectionException("LinkedList");
        }

        boolean found = false;
        LinearNode previous = null;
        LinearNode current = head;

        while (current != null && !found)
        {
            if (targetelement.equals(current.getElement()))
            {
                found = true;
            }
            else
            {
                previous = current;
                current = current.getNext();
            }
        }

        if (!found)
        {
            throw new ElementNotFoundException("LinkedList");
        }

        if (size()==1)  // 列表中只有一个元素
        {
            head = tail = null;
        }
        else if (current.equals(head))  //  目标在头
        {
            head = current.getNext();
        }
        else if (current.equals(tail))  //  目标在尾
        {
            tail = previous;
            tail.setNext(null);
        }
        else   // 目标在中间
        {
            previous.setNext(current.getNext());
        }

        count--;

        return current.getElement();
    }

        public Product first() {
        if (isEmpty()){
            throw new EmptyCollectionException("LinkedList");
        }

        Product result = head.getElement();
        return result;
    }

    public Product last() {
        if (isEmpty()){
            throw new EmptyCollectionException("LinkedList");
        }

        LinearNode temp = head;
        while(temp.getNext()!= null) {
            temp = temp.getNext();
        }

        return temp.getElement();
    }

    public boolean contains(T target) {
        LinearNode current = head;
        while (current != null && !target.equals(current.getElement())) {
            current = current.getNext();
        }

        if (current != null) {
            return true;
        } else {
            return false;
        }
    }

    public Product find(String a)
    {
        LinearNode current = head;
        while (current != null && !a.equals(current.getElement().getName())) {
            current = current.getNext();
        }
        return current.getElement();
    }

    public boolean isEmpty() {
        return count == 0;
    }

    public int size() {
        return count;
    }

    public void  selectionSort(){
        Product temp;
        LinearNode current = head;
        while(current!=null)
        {
            LinearNode node = current.getNext();
            while(node!=null) {
                if (node.getElement().compareTo(current.getElement())< 0) {
                    temp = node.getElement();
                    node.setElement(current.getElement());
                    current.setElement(temp);
                }
                node = node.getNext();
            }
            current = current.getNext();
        }
    }

    public String toString()
    {
        LinearNode temp;
        temp = head;
        String result = "";
        while(temp != null)
        {
            result += temp.getElement() + "\n";
            temp = temp.getNext();
        }
        return result;
    }
}
